#include "../include/head.h"
#include "../include/workque.h"
#include "../include/md5.h"
#include "../include/thread_Pool.h"
threadPool_t pool;
int exitPipe[2];
typedef struct clientid
{
    int cfd;
    Que_t *que;
}Client_t;
Client_t client[1024] = {0}; //保存最大连接数量
size_t cut = 0;
void* func(void *arg)
{
    puts("成功创建一个处理文件描述符的子线程\n");
    char parent_id[5]="1";
    Client_t c1 = *(Client_t*)arg;
    int userId = serverLogin(c1.cfd);
    int epd=epoll_create(2);
    epollAddFd(c1.cfd,epd);
    int sum=0;
    struct epoll_event evs[2];
    while(1)
    {
        sum = epoll_wait(epd,evs,2,-1);
        for(int i=0 ; i<sum; i++)
        {
            if(evs[i].data.fd == c1.cfd)
            {
                char arr[50]={0};
                int ret1 = recv(c1.cfd, arr, sizeof(arr), 0);
               
                if (ret1 == 0)
                {
                    break;
                }

                //ls查看当前工作目录下的所有文件

                if (!(strcmp(arr, "ls")))
                {
                    char temp[5] = {0};
                    sprintf(temp,"%d",userId);
                    printf("处理客户端的ls\n");
                    ls(c1.cfd, parent_id, temp);
                    record log;
                    strcpy(log.username, temp);
                    strcpy(log.cmd, arr);
                    insert_log(log);//写入日志文件中
                }
                if (!(strcmp(arr, "pwd")))
                {
                    char str[20];
                    sprintf(str, "%d", userId);
                    pwd(str, c1.cfd,arr);
                }
                
                char *ptmp = strchr(arr, ' '); //走到中间的空格停下来
                if (ptmp != NULL)
                {

                    char buf[20] = {0};
                    strncpy(buf, arr, (int)(ptmp - arr)); //截取命令左边的
                    if (!(strcmp(buf, "cd")))             //如果是cd命令
                    {

                        //需要截取cd右边的参数
                        char data[20] = {0};
                        strcpy(data, ptmp + 1);
                        Rtrim(data);
                        //char parent[20];
                        //sprintf(parent,"%d",parent_id);

                        char temp[10];
                        sprintf(temp,"%d",userId);
                        cd(c1.cfd, data,parent_id,temp);
                        printf("cd 之后的parent_id = %s\n",parent_id);
                        //需要修改当前工作目录的
                        record log;
                        strcpy(log.username, temp);
                        strcpy(log.cmd, arr);
                        insert_log(log);
                        
                    }
                    if(!(strcmp(buf,"puts")))
                    {
                        //上传文件
                        char data[40]={0};
                        strcpy(data,ptmp+1);//截取右边的命令
                        Rtrim(data);
                        printf("需要上传文件%s\n",arr);
                        pNode_t pNew = (pNode_t)calloc(1, sizeof(Node_t));
                        
                        
                        pNew->userid=userId;
                        pNew->clientFd=c1.cfd;
                        pNew->parent_id=atoi(parent_id);
                        
                        strcpy(pNew->order,buf);
                        
                         pthread_mutex_lock(&c1.que->mutex);
                         queInsert(&pool.Que, pNew);
                        //任务队列里面有数据了，唤醒等待的子线程
                        pthread_cond_signal(&c1.que->cond);
                        pthread_mutex_unlock(&c1.que->mutex);

                    }
                    if (!(strcmp(buf, "gets")))
                    {
                       
                        char data[20] = {0};
                        strcpy(data,ptmp+1);
                        printf("data是 %s\n",data);
                        pNode_t pNew = (pNode_t)calloc(1, sizeof(Node_t));
                        char str[20];
                        sprintf(str, "%d", userId);
                        
                        if(selectFilename(data,str)==0)
                        {
                            break;
                        }
                        pNew->clientFd = c1.cfd;
                        strcpy(pNew->order,buf);//客户端要执行的命令
                        strcpy(pNew->file,data);//客户端要操作的文件名

                        pthread_mutex_lock(&(c1.que->mutex));
                        //把节点插入到任务队列里面
                        queInsert(c1.que, pNew);
                        //任务队列里面有数据了，唤醒等待的子线程
                        pthread_cond_signal(&c1.que->cond);
                        pthread_mutex_unlock(&c1.que->mutex);

                        record log;
                        strcpy(log.username, str);
                        strcpy(log.cmd, arr);
                        insert_log(log);
                        
                    }
                }
            }
        }
    }


}
void sigFunc(int sig)
{
    printf("触发信号函数，给子进程管道写入flag\n");
    write(exitPipe[1], &sig, 4);
}

int main()
{
    //int parent_id=1;
    char parent_id[10] = "1";
    pConf_t conf = (pConf_t)calloc(1, sizeof(Conf_t));
    pConf_t phead;
    phead = load("tcp.conf", &conf);
    //打开配置文件，读取配置项

    char ip[20], port[5];
    char num[4];
    int ret;

    int str = atoi(phead->next->next->ip);
    printf("ip  = %s\tport = %s\n", phead->ip, phead->next->ip);
    printf("str : %d\n", str);
    pipe(exitPipe);
    if (fork())
    {
        close(exitPipe[0]);
        signal(SIGUSR1, sigFunc);
        wait(NULL);
    }

    //threadPool_t pool;


    threadPoolInit(&pool, str);

    //2.启动线程池

    threadPoolStart(&pool);

    //3.创建tcp监听套接字
    int sfd = 0;
    tcpInit(phead->ip, phead->next->ip, &sfd);

    //4.创建epoll
    int epfd = epoll_create(1);

    epollAddFd(sfd, epfd);
    epollAddFd(exitPipe[0], epfd);
    //将管道读端纳入监听队列
    struct epoll_event evs[2];

    int newFd = 0;
    int sums = 0;
    while (1)
    {
        sums = epoll_wait(epfd, evs, 2, -1);
        for (int i = 0; i < sums; ++i)
        {
            if (evs[i].data.fd == sfd)
            {
                newFd = accept(sfd, NULL, NULL);

                client[cut].cfd=newFd;
                client[cut].que=&pool.Que;
                pthread_t tid;
                printf("成功建立连接\n");
                //创建任务节点，newFd交给节点
                pthread_create(&tid,NULL,func,(void*)&client[cut++]);
            }
            else if (evs[i].data.fd == exitPipe[0])
            {
                for (int a = 0; a < str; a++)
                {
                    //循环遍历所有子线程
                    pool.Que.flag = 0;
                }
                for (int a = 0; a < str; a++)
                {
                    pthread_join(pool.pthid[a], NULL);
                }
            }
        }
    }
    return 0;
}
